function BuildingTessellator_line() {

}

Object.assign(BuildingTessellator_line.prototype, {

	process: function (vertexs, indexs, points, height, attr, attrStage, local, scale, id, vertexs_line,HighTerrain) {
		var nCount = points.length;
		if (nCount < 3) {
			return false;
		}

		var triangulator = new Triangulator();
		var indices = triangulator.process(points);
		if (indices == null || indices.length < 3) {
			return false;
		}

		var bClockwise = false;
		if (triangulator.area(points) < 0.0) {
			bClockwise = true;
		}

		var topPositions = [];
		var bottomPositions = [];
		for (var i = 0; i < nCount; i++) {
			var x = (points[i].x - local.x) * scale;
			var y = (points[i].y - local.y) * scale;

			topPositions.push(new Vector4(x, y, 0.0, height));
			bottomPositions.push(new Vector4(x, y, 0.0, 0.0));
		}

		var dTotalLength = 0.0;
		var subTexCoordsOffsets = [];
		for (var i = 0; i < nCount - 1; i++) {
			var x = points[i+1].x - points[i].x;
			var y = points[i+1].y - points[i].y;
			var dSubLength = Math.sqrt(x * x + y * y);
			subTexCoordsOffsets.push(dSubLength);
			dTotalLength += dSubLength;
		}
		var dCurrentLength = 0.0;
		var dMaxLength = 16;
		var texCoordsOffsets = [];
        var texNmlx = [];
		texCoordsOffsets.push(0.0);
        texNmlx.push(0.0);
		for (var i = 0; i < nCount - 1; i++) {
			dCurrentLength += subTexCoordsOffsets[i];
			texCoordsOffsets.push(dCurrentLength / dTotalLength);
            texNmlx.push(dCurrentLength / dMaxLength);
		}

		var nVertexCount = vertexs.length;
		this.processBuilding(vertexs, points, height, attr, attrStage, topPositions, bottomPositions, texCoordsOffsets, texNmlx, id,HighTerrain);


		for (var i = 0; i < nCount; i++) {
			if (i != 0) {
				var vec1 = vertexs[nVertexCount + nCount + 4*(i-1) + 0].position;
				var vec2 = vertexs[nVertexCount + nCount + 4*(i-1) + 1].position;
				var vec3 = vertexs[nVertexCount + nCount + 4*(i-1) + 2].position;

				var vecResult = null;
				if (bClockwise) {
					vecResult = this.computeFaceNormal(new Vector3(vec1.x, vec1.y, vec1.z+vec1.w), new Vector3(vec3.x, vec3.y, vec3.z+vec3.w), new Vector3(vec2.x, vec2.y, vec2.z+vec2.w));
				} else {
					vecResult = this.computeFaceNormal(new Vector3(vec1.x, vec1.y, vec1.z+vec1.w), new Vector3(vec2.x, vec2.y, vec2.z+vec2.w), new Vector3(vec3.x, vec3.y, vec3.z+vec3.w));
				}
				vertexs[nVertexCount + nCount + 4*(i-1) + 0].normal = vecResult;
				vertexs[nVertexCount + nCount + 4*(i-1) + 1].normal = vecResult;
				vertexs[nVertexCount + nCount + 4*(i-1) + 2].normal = vecResult;
				vertexs[nVertexCount + nCount + 4*(i-1) + 3].normal = vecResult;
			}
		}
		//顶面三角形索引下标
		for (var i = 0; i < indices.length; i++) {
			indexs.push(nVertexCount + indices[i]);
		}

		//侧面三角形索引下标
		indices.length = 6 * (nCount-1);
		for (var i = 0, nOffset = 0; i < nCount-1; i++) {
			if (bClockwise) {
				indices[nOffset + 0] = nCount + 4*i;
				indices[nOffset + 1] = nCount + 4*i + 2;
				indices[nOffset + 2] = nCount + 4*i + 1;

				indices[nOffset + 3] = nCount + 4*i + 2;
				indices[nOffset + 4] = nCount + 4*i + 3;
				indices[nOffset + 5] = nCount + 4*i + 1;
			} else {
				indices[nOffset + 0] = nCount + 4*i;
				indices[nOffset + 1] = nCount + 4*i + 1;
				indices[nOffset + 2] = nCount + 4*i + 3;

				indices[nOffset + 3] = nCount + 4*i + 2;
				indices[nOffset + 4] = nCount + 4*i;
				indices[nOffset + 5] = nCount + 4*i + 3;
			}
			nOffset += 6;
		}
		for (var i = 0; i < indices.length; i++) {
			indexs.push(nVertexCount + indices[i]);
		}

		if ( vertexs_line ) {
			// outline
			var nVertexCountL = vertexs_line.length;
			vertexs_line.length = nVertexCountL + (nCount-1) * 4;
			for (var i = nVertexCountL; i < vertexs_line.length; i++) {
				vertexs_line[i] = {};
			}

			for (var i = 0; i < nCount-1; i++) {
				var top = topPositions[i];
				var top1 = topPositions[i+1];
				var bot = bottomPositions[i];
				vertexs_line[nVertexCountL + i*4 + 0].position = new Vector4(top.x, top.y, top.z, top.w);
				vertexs_line[nVertexCountL + i*4 + 1].position = new Vector4(bot.x, bot.y, bot.z, bot.w);

				vertexs_line[nVertexCountL + i*4 + 2].position = new Vector4(top.x, top.y, top.z, top.w);
				vertexs_line[nVertexCountL + i*4 + 3].position = new Vector4(top1.x, top1.y, top1.z, top1.w);
			}
		}
		return true;
	},

	processBuilding: function (vertexs, points, height, attr, attrStage, topPositions, bottomPositions, texCoordsOffsets, texNmlx, id,HighTerrain) {
		var nCount = points.length;
		var nVertexCount = vertexs.length;
		vertexs.length = nVertexCount + nCount + 4*nCount - 4;
		for (var i = nVertexCount; i < vertexs.length; i++) {
			vertexs[i] = {};
		}

		var topv = Math.floor(height/4+0.1); //1.0
		for (var i = 0; i < nCount; i++) {
			var position = topPositions[i];
            var texCoordX = texCoordsOffsets[i];
            var texNmx = texNmlx[i];

			vertexs[nVertexCount + i].position = new Vector4(position.x, position.y, position.z, position.w);
			vertexs[nVertexCount + i].normal = new Vector3(0, 0, 1);
			vertexs[nVertexCount + i].uv = new Vector2(texCoordX, topv);
            vertexs[nVertexCount + i].height = height;
            vertexs[nVertexCount + i].attrv = attr;
            vertexs[nVertexCount + i].attrStage = attrStage;
			vertexs[nVertexCount + i].nxnmlx = new Vector2(i, texNmx);
			vertexs[nVertexCount + i].id = id;
			vertexs[nVertexCount + i].HighTerrain = HighTerrain;

			if (i != 0) {
				position = topPositions[i];
				vertexs[nVertexCount + nCount + 4*i - 2].position = new Vector4(position.x, position.y, position.z, position.w);
				vertexs[nVertexCount + nCount + 4*i - 2].uv = new Vector2(texCoordX, topv);
                vertexs[nVertexCount + nCount + 4*i - 2].height = height;
                vertexs[nVertexCount + nCount + 4*i - 2].attrv = attr;
                vertexs[nVertexCount + nCount + 4*i - 2].attrStage = attrStage;
				vertexs[nVertexCount + nCount + 4*i - 2].nxnmlx = new Vector2(i, texNmx);
				vertexs[nVertexCount + nCount + 4*i - 2].id = id;
				vertexs[nVertexCount + nCount + 4*i - 2].HighTerrain = HighTerrain;

				position = bottomPositions[i];
				vertexs[nVertexCount + nCount + 4*i - 1].position = new Vector4(position.x, position.y, position.z, position.w);
				vertexs[nVertexCount + nCount + 4*i - 1].uv = new Vector2(texCoordX, 0.0);
                vertexs[nVertexCount + nCount + 4*i - 1].height = height;
                vertexs[nVertexCount + nCount + 4*i - 1].attrv = attr;
                vertexs[nVertexCount + nCount + 4*i - 1].attrStage = attrStage;
				vertexs[nVertexCount + nCount + 4*i - 1].nxnmlx = new Vector2(i, texNmx);
				vertexs[nVertexCount + nCount + 4*i - 1].id = id;
				vertexs[nVertexCount + nCount + 4*i - 1].HighTerrain = HighTerrain;
			}
			if (i != nCount-1) {
				position = topPositions[i];
				vertexs[nVertexCount + nCount + 4*i].position = new Vector4(position.x, position.y, position.z, position.w);
				vertexs[nVertexCount + nCount + 4*i].uv = new Vector2(texCoordX, topv);
                vertexs[nVertexCount + nCount + 4*i].height = height;
                vertexs[nVertexCount + nCount + 4*i].attrv = attr;
                vertexs[nVertexCount + nCount + 4*i].attrStage = attrStage;
				vertexs[nVertexCount + nCount + 4*i].nxnmlx = new Vector2(i, texNmx);
				vertexs[nVertexCount + nCount + 4*i].id = id;
				vertexs[nVertexCount + nCount + 4*i].HighTerrain = HighTerrain;

				position = bottomPositions[i];
				vertexs[nVertexCount + nCount + 4*i + 1].position = new Vector4(position.x, position.y, position.z, position.w);
				vertexs[nVertexCount + nCount + 4*i + 1].uv = new Vector2(texCoordX, 0.0);
                vertexs[nVertexCount + nCount + 4*i + 1].height = height;
                vertexs[nVertexCount + nCount + 4*i + 1].attrv = attr;
                vertexs[nVertexCount + nCount + 4*i + 1].attrStage = attrStage;
				vertexs[nVertexCount + nCount + 4*i + 1].nxnmlx = new Vector2(i, texNmx);
				vertexs[nVertexCount + nCount + 4*i + 1].id = id;
				vertexs[nVertexCount + nCount + 4*i + 1].HighTerrain = HighTerrain;
			}
		}
	},

	toTransferableObjects: function (vertexBuffers, indexBuffers, vertexBuffers_line, local, transferableObjects) {
		var layouts = [];
		for (var i = 0; i < vertexBuffers.length; i++) {
			var indices = new Uint16Array(indexBuffers[i].length);
			var vertices = new Float32Array(vertexBuffers[i].length * 3);
			var normals = new Float32Array(vertexBuffers[i].length * 3);
			var uvs = new Float32Array(vertexBuffers[i].length * 2);
			var heights =  new Float32Array(vertexBuffers[i].length );
			var localxys = new Float32Array(vertexBuffers[i].length * 2);
			var attrs = new Float32Array(vertexBuffers[i].length );
            var attrstage = new Float32Array(vertexBuffers[i].length );
			var nxnmlxs = new Float32Array(vertexBuffers[i].length * 2);
			var ids = new Float32Array(vertexBuffers[i].length );
			var highTerrains = new Float32Array(vertexBuffers[i].length );

			for (var j = 0; j < vertexBuffers[i].length; j++) {
				var vertex = vertexBuffers[i][j];

				vertices[j * 3 + 0] = vertex.position.x;
				vertices[j * 3 + 1] = vertex.position.y;
				vertices[j * 3 + 2] = vertex.position.z + vertex.position.w;

				normals[j * 3 + 0] = vertex.normal.x;
				normals[j * 3 + 1] = vertex.normal.y;
				normals[j * 3 + 2] = vertex.normal.z;

				uvs[j * 2 + 0] = vertex.uv.x;
				uvs[j * 2 + 1] = vertex.uv.y;

                heights[j] = vertex.height;
                localxys[j * 2 + 0] = local.x;
                localxys[j * 2 + 1] = local.y;
                attrs[j] = vertex.attrv;
                attrstage[j] = vertex.attrStage;

                nxnmlxs[j * 2 + 0] = vertex.nxnmlx.x;
				nxnmlxs[j * 2 + 1] = vertex.nxnmlx.y;
				
				ids[j] = vertex.id;

				highTerrains[j]=vertex.HighTerrain;
			}
			for (var j = 0; j < indexBuffers[i].length; j++) {
				indices[j] = indexBuffers[i][j];
			}

			transferableObjects.face.push(vertices.buffer);
			transferableObjects.face.push(normals.buffer);
			transferableObjects.face.push(uvs.buffer);
            transferableObjects.face.push(heights.buffer);
            transferableObjects.face.push(localxys.buffer);
            transferableObjects.face.push(attrs.buffer);
            transferableObjects.face.push(attrstage.buffer);
			transferableObjects.face.push(nxnmlxs.buffer);
			transferableObjects.face.push(ids.buffer);
			transferableObjects.face.push(indices.buffer);
			transferableObjects.face.push(highTerrains.buffer);

			var nums = 11;
			var layout = {
				attribs: [
					{name: 'position', itemSize: 3, normalized: 0, type: 0, index: nums * i + 0},
					{name: 'normal', itemSize: 3, normalized: 0, type: 0, index: nums * i + 1},
					{name: 'uv', itemSize: 2, normalized: 0, type: 0, index: nums * i + 2},
                    {name: 'height', itemSize: 1, normalized: 0, type: 0, index: nums * i + 3},
                    {name: 'local', itemSize: 2, normalized: 0, type: 0, index: nums * i + 4},
                    {name: 'attrv', itemSize: 1, normalized: 0, type: 0, index: nums * i + 5},
                    {name: 'attrstage', itemSize: 1, normalized: 0, type: 0, index: nums * i + 6},
					{name: 'nxnmlxs', itemSize: 2, normalized: 0, type: 0, index: nums * i + 7},
					{name: 'id', itemSize: 1, normalized: 0, type: 0, index: nums * i + 8},
					{name: 'highTerrain', itemSize: 1, normalized: 0, type: 0, index: nums * i + 10},
				],
				index: {name: 'index', itemSize: 1, normalized: 0, type: 0, index: nums * i + 9}
			};
			layouts.push(layout);
		}

		var layouts_line = null;
		if ( vertexBuffers_line ) {
			var layouts_line = [];
			for (var i = 0; i < vertexBuffers_line.length; i++) {
				var vertices = new Float32Array(vertexBuffers_line[i].length * 3);

				for (var j = 0; j < vertexBuffers_line[i].length; j++) {
					var vertex = vertexBuffers_line[i][j];

					vertices[j * 3 + 0] = vertex.position.x;
					vertices[j * 3 + 1] = vertex.position.y;
					vertices[j * 3 + 2] = vertex.position.z + vertex.position.w;
				}

				transferableObjects.line.push(vertices.buffer);

				var nums = 1;
				var layout = {
					attribs: [
						{name: 'position', itemSize: 3, normalized: 0, type: 0, index: 1 * i + 0},
					]
				};
				layouts_line.push(layout);
			}
		}

        var lyout = {face: layouts, line: layouts_line};
		return lyout;
	},

	computeFaceNormal: function (vec1, vec2, vec3) {
		return (vec2.sub(vec1)).cross(vec3.sub(vec2)).normalized();
	},

} );



